﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.ComponentModel;
using Devtm.Generator.Contexts;
using System.CodeDom;

namespace Devtm.Generator
{


    public abstract class ScriptIntegrator
    {

        internal const string Empty = "Empty";
    
    }

    [DisplayName(ScriptIntegrator.Empty)]
    [Description(ScriptIntegrator.Empty)]
    [Guid("00000000-0000-0000-0000-000000000000")]
    public abstract class ScriptIntegrator<TContext> : IScript<TContext>
        where TContext : IContext, new()
    {

        private static string name;


        static ScriptIntegrator()
        {
            name = typeof(ScriptIntegrator).Assembly.GetName().Name;
        }


        public ScriptIntegrator()
        {
            Type t = GetType();
            ClassName = string.Format("{0}.{1}", t.Namespace, t.Name)
                .Replace(".", "")
                .Replace("_", "");
        }


        public void Run(TContext context)
        {

            var gen = new Devtm.Generator.Generator<Devtm.Generator.Writers.CodeWriter, TContext>(context);
            
            gen.NewWriter(PathNamespace, ClassName);

            // create new namespace
            using (var n = gen.Writer.AddNamespace(PathNamespace))
            {

                // create new class
                using (var t = gen.Writer.AddClass(ClassName, MemberAttributes.Public))
                {

                    var t1 = typeof(string).TypeReference();
                    gen.Writer.AddPropertyGetSet(t1, "ClassName", Writers.propertyNum.All, MemberAttributes.Public);
                    gen.Writer.AddPropertyGetSet(t1, "PathNamespace", Writers.propertyNum.All, MemberAttributes.Public);
                  
                    // create new method
                    using (var method = gen.Writer.AddMethod(typeof(void), "Run", MemberAttributes.Public))
                    {

                        method.Item.Parameters.Add(new CodeParameterDeclarationExpression(typeof(IContext).TypeReference(), "context"));

                        Run(context, gen, method.Item);

                    }

                }
            }

            gen.SaveWriter(PathNamespace);

        }

        protected abstract void Run(IContext context, Generator<Writers.CodeWriter, TContext> gen, CodeMemberMethod codeMemberMethod);


        public static void Analyze(string file)
        {

         
        }


        public string ClassName { get; set; }

        public string PathNamespace { get; set; }


    }


    public struct ScriptItem
    {
        public Guid Key { get; internal set; }
        public Guid Name { get; internal set; }
        public Guid Description { get; internal set; }
        public string Type { get; internal set; }
        public string AssemblyFile { get; internal set; }
    }

}
